package com.wzz.common.calendar.views;

import java.util.Calendar;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.MonthDisplayHelper;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;

import com.hymobile.common.R;

public class CalendarView extends ImageView implements OnGestureListener {
  @SuppressWarnings("unused")
  private static final String TAG = "CalendarView";
  /**
   * 左右滑动的移动速度
   */
  private static final int MOVE_SPEED = 20;
  /**
   * 左右滑动的移动距离
   */
  private static final int MOVE_LENGTH = 80;
  /**
   * 整个日历的上边距
   */
  private static int WEEK_TOP_MARGIN = 74;
  /**
   * 整个日历的左边距
   */
  private static int WEEK_LEFT_MARGIN = 40;

  /**
   * 单元格的宽
   */
  private static int CELL_WIDTH = 58;
  /**
   * 单元格的高
   */
  private static int CELL_HEIGH = 53;
  /**
   * 单元格的上边距
   */
  private static int CELL_MARGIN_TOP = 92;
  /**
   * 单元格的左边距
   */
  private static int CELL_MARGIN_LEFT = 39;

  /**
   * 文字大小
   */
  private static float CELL_TEXT_SIZE = 26.0f;

  /**
   * 当前日期的日历对象
   */
  private Calendar rightNow = null;
  /** 装饰物，默认为选择当天的那个圆圈 **/
  private Drawable decoration = null;
  /**
   * 日历的表头
   */
  private Drawable weekTitle = null;
  /**
   * 今天得日期格子
   */
  private Cell todayCell = null;
  /**
   * 格子列表
   */
  private Cell[][] cells = new Cell[6][7];
  /**
   * 事件监听器
   */
  private OnCellTouchListener onCellTouchListener = null;

  MonthDisplayHelper helper;
  private Calendar targetDay;
  private Calendar startDay;
  private Calendar endDay;
  private boolean isEdit = true;
  private CellFactory cellFactory;
  private GestureDetector gestureDetector; // 手势识别

  public CalendarView(Context context) {
    this(context, null);
  }

  public CalendarView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public CalendarView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    decoration = context.getResources().getDrawable(R.drawable.calendar_today_typeb);
    gestureDetector = new GestureDetector(this);
    gestureDetector.setIsLongpressEnabled(true);
    initCalendarView();
  }

  // public static String getDisplayMetrics() {
  // String str = "";
  // DisplayMetrics dm = new DisplayMetrics();
  // dm = ctx.getApplicationContext().getResources().getDisplayMetrics();
  // int screenWidth = dm.widthPixels;
  // int screenHeight = dm.heightPixels;
  // float density = dm.density;
  // float xdpi = dm.xdpi;
  // float ydpi = dm.ydpi;
  // str += "The absolute width:" + String.valueOf(screenWidth) + "pixels\n";
  // str += "The absolute heightin:" + String.valueOf(screenHeight) + "pixels\n";
  // str += "The logical density of the display.:" + String.valueOf(density) + "\n";
  // str += "X dimension :" + String.valueOf(xdpi) + "pixels per inch\n";
  // str += "Y dimension :" + String.valueOf(ydpi) + "pixels per inch\n";
  // return str;
  // }

  /**
   * 初始化日历基础信息，包括尺寸，背景图，标题，单元格间距，尺寸，等
   */
  private void initCalendarView() {
    rightNow = Calendar.getInstance();

    Resources res = getResources();
    // 设置整体日历间距
    WEEK_TOP_MARGIN = (int) res.getDimension(R.dimen.week_top_margin);
    WEEK_LEFT_MARGIN = (int) res.getDimension(R.dimen.week_left_margin);

    // 设置Cell格子宽高
    CELL_WIDTH = (int) res.getDimension(R.dimen.cell_width);
    CELL_HEIGH = (int) res.getDimension(R.dimen.cell_heigh);
    // 设置格子间距
    CELL_MARGIN_TOP = (int) res.getDimension(R.dimen.cell_margin_top);
    CELL_MARGIN_LEFT = (int) res.getDimension(R.dimen.cell_margin_left);
    // 设置文字大小
    CELL_TEXT_SIZE = res.getDimension(R.dimen.cell_text_size);
    // 设置日历背景
    setImageResource(R.drawable.calendar_background);
    setPadding(0, 0, 0, 0);
    // 设置日历表头
    weekTitle = res.getDrawable(R.drawable.calendar_week);
    weekTitle.setBounds(WEEK_LEFT_MARGIN, WEEK_TOP_MARGIN, WEEK_LEFT_MARGIN + weekTitle.getMinimumWidth(),
        WEEK_TOP_MARGIN + weekTitle.getMinimumHeight());

    helper = new MonthDisplayHelper(rightNow.get(Calendar.YEAR), rightNow.get(Calendar.MONTH));
    cellFactory = CellFactory.getInstance(CELL_TEXT_SIZE);
    initCells();
  }

  private void initCells() {
    cellFactory.setHelper(helper);

    if (targetDay == null) {
      targetDay = Calendar.getInstance();
    }
    /** 当前日期 **/
    int thisDay = 0;
    /** 今天的格子 **/
    todayCell = null;

    if (helper.getYear() == targetDay.get(Calendar.YEAR) && helper.getMonth() == targetDay.get(Calendar.MONTH)) {
      thisDay = targetDay.get(Calendar.DAY_OF_MONTH);
    }

    Rect bound = new Rect(CELL_MARGIN_LEFT, CELL_MARGIN_TOP, CELL_WIDTH + CELL_MARGIN_LEFT, CELL_HEIGH
        + CELL_MARGIN_TOP);

    for (int week = 0; week < 6; week++) {
      for (int day = 0; day < 7; day++) {
        int tDay = helper.getDigitsForRow(week)[day];
        if (helper.isWithinCurrentMonth(week, day)) {
          if (day == 0 || day == 6) { // 如果是周六和周日，红色字体
            cells[week][day] = cellFactory.create(CellFactory.RED, tDay, bound);
          } else { // 平常日期没有任何特殊显示
            cells[week][day] = cellFactory.create(CellFactory.NONE, tDay, bound);
          }
        } else { // 如果是不是当前月，则显示灰色
          cells[week][day] = cellFactory.create(CellFactory.GRAY, tDay, bound);
        }

        if (startDay != null && endDay != null) {
          Calendar c = cells[week][day].getDate();
          if (c.after(startDay) && c.before(endDay)) {
            if (cells[week][day].isThisMonth) {
              cells[week][day].setBackColor(true, 0x330000ff);
            }
          }
        }

        bound.offset(CELL_WIDTH, 0); // move to next column

        // get today
        if (tDay == thisDay) {
          todayCell = cells[week][day];
          if (cells[week][day].isThisMonth) {
            decoration.setBounds(todayCell.getBound());// 设置当期日期画圈的边界为 当前格子的方块
          }
        }
      }
      bound.offset(0, CELL_HEIGH); // move to next row and first column
      bound.left = CELL_MARGIN_LEFT;
      bound.right = CELL_MARGIN_LEFT + CELL_WIDTH;
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // draw background
    super.onDraw(canvas);
    weekTitle.draw(canvas);

    // draw cells
    for (Cell[] week : cells) {
      for (Cell day : week) {
        day.draw(canvas);
      }
    }

    // draw today
    if (decoration != null && todayCell != null) {
      decoration.draw(canvas);
    }

  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
  }

  public void setTimeInMillis(long milliseconds) {
    rightNow.setTimeInMillis(milliseconds);
    refresh();
  }

  /**
   * 设置点击监听器
   * 
   * @param p
   */
  public void setOnCellTouchListener(OnCellTouchListener p) {
    onCellTouchListener = p;
  }

  /**
   * 获得当期年
   * 
   * @return
   */
  public int getYear() {
    return helper.getYear();
  }

  /**
   * 获得当前月份
   * 
   * @return
   */
  public int getMonth() {
    return helper.getMonth();
  }

  /**
   * 获得当前日期
   * 
   * @return
   */
  public Calendar getDate() {
    return rightNow;
  }

  /**
   * 下一个月
   */
  public void nextMonth() {
    helper.nextMonth();
    refresh();
    onCellTouchListener.onMonthChange();
  }

  /**
   * 前一个月
   */
  public void previousMonth() {
    helper.previousMonth();
    refresh();
    onCellTouchListener.onMonthChange();
  }

  /**
   * 跳转到当天
   */
  public void goToday() {
    Calendar cal = Calendar.getInstance();
    helper = new MonthDisplayHelper(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH));
    refresh();
    onCellTouchListener.onMonthChange();
  }

  /**
   * 跳转到指定日期
   * 
   * @param cal
   */
  public void gotoDay(Calendar cal) {
    helper = new MonthDisplayHelper(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH));
    targetDay = cal;
    refresh();
    onCellTouchListener.onMonthChange();
  }

  public void setBackground(Calendar begin, Calendar end) {
    startDay = begin;
    endDay = end;
    refresh();
  }

  /**
   * 初始化格子，并重绘
   */
  private void refresh() {
    initCells();
    invalidate();
  }

  /**
   * 根据事件触发的坐标判断当前在哪个格子里面触发。
   * 
   * @param x
   *          事件的X坐标
   * @param y
   *          事件的Y坐标
   * @return 当前坐标所在的格子
   */
  private Cell findEventCell(float x, float y) {
    for (Cell[] week : cells) {
      for (Cell day : week) {
        if (day.hitTest((int) x, (int) y) && day.isThisMonth) {
          return day;
        }
      }
    }
    return null;
  }

  /**
   * 左右滑动切换月份
   * 
   * @param e1
   * @param e2
   * @param velocityX
   * @param velocityY
   * @return
   * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent,
   *      float, float)
   */
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if ((e1.getX() - e2.getX() > MOVE_LENGTH) && Math.abs(velocityX) > MOVE_SPEED) {
      nextMonth();
    } else if ((e2.getX() - e1.getX() > MOVE_LENGTH) && Math.abs(velocityX) > MOVE_SPEED) {
      previousMonth();
    }
    return true;
  }

  /**
   * 点击事件
   * 
   * @param e
   * @return
   * @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent)
   */
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
    if (onCellTouchListener != null) {
      Cell day = findEventCell(e.getX(), e.getY());
      if (day != null) {
        if (isEdit) {
          if (day.isFill) {
            day.setBackColor(false, 0x00000000);
          } else {
            day.setBackColor(true, 0x330000ff);
          }
        }
        onCellTouchListener.onTouch(day);
        invalidate();
      }
    }
    return true;
  }

  /**
   * 长按事件。
   * 
   * @param e
   * @see android.view.GestureDetector.OnGestureListener#onLongPress(android.view.MotionEvent)
   */
  @Override
  public void onLongPress(MotionEvent e) {
    if (onCellTouchListener != null) {
      Cell day = findEventCell(e.getX(), e.getY());
      if (day != null) {
        if (isEdit) {
          if (day.isFill) {
            day.setBackColor(false, 0x00000000);
          } else {
            day.setBackColor(true, 0x330ff0ff);
          }

        }
        onCellTouchListener.onLongTouch(day);
        invalidate();
      }
    }
  }

  @Override
  public boolean onDown(MotionEvent e) {
    return true;
  }

  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    return true;
  }

  @Override
  public void onShowPress(MotionEvent e) {
  }

  public interface OnCellTouchListener {
    /**
     * 点击事件
     * 
     * @param cell
     *          当前点击的日历格子
     */
    public void onTouch(Cell cell);

    /**
     * 长按事件
     * 
     * @param cell
     *          当前点击的日历格子
     */
    public void onLongTouch(Cell cell);

    /**
     * 日历月份改变事件
     */
    public void onMonthChange();
  }

}
